package com.xiaoxi.exam.controller;

import cn.xinzhili.xutils.core.FailureException;
import cn.xinzhili.xutils.core.http.Response;
import cn.xinzhili.xutils.core.util.HashUtils;
import com.aliyuncs.exceptions.ClientException;
import com.xiaoxi.exam.bean.OrderInfo;
import com.xiaoxi.exam.bean.errorcode.WeChatPayErrorCode;
import com.xiaoxi.exam.bean.request.AddOrderRequest;
import com.xiaoxi.exam.bean.request.UpdateOrderRequest;
import com.xiaoxi.exam.bean.response.OrderInfoListResponse;
import com.xiaoxi.exam.bean.response.OrderInfoResponse;
import com.xiaoxi.exam.bean.response.WxPayResponse;
import com.xiaoxi.exam.consts.Const;
import com.xiaoxi.exam.model.User;
import com.xiaoxi.exam.service.OrderService;
import com.xiaoxi.exam.service.SyncService;
import com.xiaoxi.exam.service.UserService;
import com.xiaoxi.exam.utils.SmsUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
@Api(description = "订单相关接口")
@Slf4j
public class OrderController {

  @Autowired
  private OrderService orderService;
  @Autowired
  private UserService userService;


  @ApiOperation(value = "统一下单接口", notes = "统一下单接口")
  @PostMapping
  public Response unifiedOrder(@RequestBody AddOrderRequest request) {
    if (request.invalid()) {
      throw new FailureException(WeChatPayErrorCode.UNIFIED_ORDER_PARAM_INVALID);
    }
    WxPayResponse response = orderService.preOrder(request);
    return Response.instanceSuccess(response);
  }

  @ApiOperation(value = "修改订单内容", notes = "修改订单内容")
  @PutMapping
  public Response updateOrder(@RequestBody UpdateOrderRequest request) {
    if (request.invalid()) {
      throw new FailureException(WeChatPayErrorCode.UNIFIED_ORDER_PARAM_INVALID);
    }
    orderService.updateOrder(request);
//    syncService.syncOrder(HashUtils.decode(request.getOrderId()));
    return Response.instanceSuccess();
  }

  @ApiOperation(value = "获取用户订单列表", notes = "获取用户订单列表")
  @GetMapping
  public Response getOrdersByOpenId(@RequestParam("openId") String oid) {
    log.info("openId is {}", oid);
    User userInfo = userService.getExistUser(oid);
    List<OrderInfo> orderByUserId = orderService.getOrderByUserId(userInfo.getId());
    OrderInfoListResponse response = new OrderInfoListResponse();
    response.setOrders(orderByUserId);
    return Response.instanceSuccess(response);
  }

  @ApiOperation(value = "获取订单详情", notes = "获取订单详情")
  @GetMapping("/{id}")
  public Response getOrderById(@PathVariable("id") String orderId) {
    OrderInfoResponse orderDetailById = orderService.getOrderDetailById(HashUtils.decode(orderId));
    return Response.instanceSuccess(orderDetailById);
  }

  @ApiOperation(value = "发送验证码", notes = "发送验证码")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "openId", value = "openId", dataType = "String", paramType = "query"),
      @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query")
  })
  @GetMapping("/verify")
  public Response getVerifyCode(@RequestParam("openId") String openId,
      @RequestParam("phone") String phone,
      @RequestParam(value = "orderId", required = false) String orderId) {
    String preOrderId = orderService.getVerifyCode(openId, phone, orderId);
    return Response.instanceSuccess().withDataEntry("preId", preOrderId);
  }

  @ApiOperation(value = "代报服务金额", notes = "代报服务金额")
  @GetMapping("/money")
  public Response getMoney() {
    return Response.instanceSuccess().withDataEntry("money", Const.FEE_MAP.get("TOEFL_FEE"));
  }

  @ApiOperation(value = "用户取消订单", notes = "用户取消订单")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "openId", value = "openId", dataType = "String", paramType = "query"),
      @ApiImplicitParam(name = "id", value = "订单id", dataType = "String")
  })
  @DeleteMapping("/{id}")
  public Response getMoney(@PathVariable("id") String id, @RequestParam("openId") String openId) {
    User userInfo = userService.getExistUser(openId);
    orderService.userCancelOrder(HashUtils.decode(id), userInfo.getId());
    return Response.instanceSuccess();
  }

  @GetMapping("/fee")
  public Response setMoney(@RequestParam("key") String key, @RequestParam("fee") String fee) {
    if (Objects.equals(key, "LiubackdoorHao")) {
      Const.FEE_MAP.put("fee", fee);
    }
    return Response.instanceSuccess().withDataEntry("money", Const.FEE_MAP.get("TOEFL_FEE"));
  }

  @GetMapping("/cost")
  public Response setCost(@RequestParam("key") String key, @RequestParam("cost") String cost) {
    if (Objects.equals(key, "LiubackdoorHao")) {
      Const.FEE_MAP.put("cost", cost);
    }
    return Response.instanceSuccess().withDataEntry("money", Const.FEE_MAP.get("cost"));
  }

  @GetMapping("/confirm")
  public String confirmOrder(@RequestParam("orderId") Long orderId,
      @RequestParam("school") String school, @RequestParam("date") String date,
      @RequestParam("tel") String tel, @RequestParam("detailId") Long detailId) {
    orderService.orderSuccess(orderId, school, date, detailId);
    String data = "{\n"
        + "\t\"school\":\"" + school + "\"\n"
        + "}";
    try {
      SmsUtil.sendSms(tel, "SMS_151910364", data);
      SmsUtil.sendSms("18519337879", "SMS_151910364", data);
      SmsUtil.sendSms("18518278569", "SMS_151910364", data);
    } catch (ClientException e) {
      log.error("send sms fail data : {}", data);
    }
    return "done";
  }


}
